package io.gitee.chearnee.fw.tools.processor;

import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.TypeSpec;
import com.sun.source.tree.ModifiersTree;
import com.sun.source.tree.Tree;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeTranslator;
import com.sun.tools.javac.util.List;
import io.gitee.chearnee.fw.tools.BaseAbstractProcessor;

import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * @author cn
 * @version 1.0
 * @description
 * @date 1/5/2023 6:24 PM
 */
public class FieldProcessor extends BaseAbstractProcessor<SDFieldSuffixMark> {

    public FieldProcessor(){
        //  document why this constructor is empty
        addOpensForLombok();
    }


    @Override
    public boolean annotationProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        this.messager.printMessage(Diagnostic.Kind.NOTE, "中文字参赛歌手");
        Set<? extends Element> dataElements = roundEnv.getElementsAnnotatedWith(getAnnotationType());
        for (Element dataElement : dataElements) {
//            if(dataElement.getKind() != ElementKind.FIELD){
//                continue;
//            }
            buildSdString(dataElement);
        }
        return false;
    }


    private void buildSdString(Element dataElement) {
        SDFieldSuffixMark annotation = dataElement.getAnnotation(getAnnotationType());
        String extensionName = buildNameExtension(dataElement, annotation);
        FieldSpec android = FieldSpec.builder(String.class, extensionName)
                .addModifiers(Modifier.PRIVATE)
                .build();

        JCTree tree = javacTrees.getTree(dataElement);
        tree.accept(new TreeTranslator(){
            @Override
            public void visitVarDef(JCTree.JCVariableDecl tree) {
                super.visitVarDef(tree);
            }

            @Override
            public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
                List<JCTree.JCVariableDecl> jcVariableDeclList = List.nil();
                for (JCTree tree : jcClassDecl.defs) {
                    if (tree.getKind().equals(Tree.Kind.VARIABLE)) {
                        JCTree.JCVariableDecl jcVariableDecl = (JCTree.JCVariableDecl) tree;
                        jcVariableDeclList = jcVariableDeclList.append(jcVariableDecl);
                    }
                }
                jcVariableDeclList.forEach(jcVariableDecl -> {
                    jcClassDecl.defs = jcClassDecl.defs.prepend(
                            treeMaker.VarDef(treeMaker.Modifiers(Modifier.PRIVATE.ordinal()), names.fromString("age"), treeMaker.Ident(names.fromString("String")), null));

                });
                super.visitClassDef(jcClassDecl);
            }
        });


        this.messager.printMessage(Diagnostic.Kind.WARNING, android.toString());
        String packageName = elementUtils.getPackageOf(dataElement).getQualifiedName().toString();
        TypeSpec fff = TypeSpec.classBuilder("fff")
                .addField(android)
                .build();
        JavaFile javaFile = JavaFile.builder(packageName,fff)
                .build();
        try {
            javaFile.writeTo(filer);
        } catch (IOException e) {
        }
    }


    private String buildNameExtension(Element dataElement, SDFieldSuffixMark annotation) {
        return dataElement.getSimpleName().toString() + annotation.value();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        HashSet<String> strings = new HashSet<>();
        strings.add(SDFieldSuffixMark.class.getName());
        return strings;
    }

    @Override
    public Class<SDFieldSuffixMark> getAnnotationType() {
        return SDFieldSuffixMark.class;
    }
}
